import { shell } from "electron";
import fs from "node:fs";
import utils from "./utils";
import { closeDatabase } from "../database/index";
import logger, { deleteHistoryLog } from "../logger"
// const { updateBuild, getBuildVersion } = require("./upgrade");
let timeoutId = 0; // Set timeout id

export const ipcAppInit = (app: any, ipcMain: any) => {
  // Get the version number
  ipcMain.handle("appVersion", async () => {
    return {
      app: app.getVersion(),
      upgrade: global?.upgrade?.buildVersion,
      build: global?.upgrade?.buildPath,
    };
  });
  // Exit
  ipcMain.handle("appQuit", async () => {
    deleteHistoryLog();
    await closeDatabase();
    app.quit();
    app.exit(0);
  });
  // Restart
  ipcMain.handle("appRestart", async (event: any) => {
    app.relaunch({ args: process.argv.slice(1).concat(['--relaunch']) });
    app.exit(0);
  });
  // Open link
  ipcMain.handle("openLink", async (event: any, url: any) => {
    let isValid = false;
    try {
      let urlObj = new URL(url);
      if (urlObj.protocol == "http:" || urlObj.protocol == "https:") {
        isValid = true;
      }
    } catch (_) { }
    if (!isValid) {
      console.error("Invalid URL:", url);
      return Promise.reject(`Invalid URL:${url}`);
    }
    return shell.openExternal(url);
  });
  //install
  ipcMain.handle("install", async (event: any, file_path: any) => {
    console.log("install", file_path);
    if (!file_path || !fs.existsSync(file_path)) {
      return Promise.reject("Invalid file path");
    }
    if (process.platform === "darwin") {
      shell.openExternal(`file://${file_path}`).then(function () {
        app.exit(0);
      });
    } else {
      shell.openPath(file_path).then(function () {
        app.exit(0);
      });
    }
  });
  // Hot Update
  ipcMain.handle("hotUpdate", async (event: any, version: any, hotUrl: any, diffUrl: any) => {
    console.log("hotUpdate", version, hotUrl, diffUrl);
    // return updateBuild(version, hotUrl, diffUrl);
  });
  // Open a folder and return the result
  ipcMain.handle("openFolder", async (event: any, folderName: any) => {
    const userPath = path.join(app.getPath("userData"), "apipost", folderName);
    try {
      const stats = await fs.stat(userPath);
      if (stats.isDirectory()) {
        shell.openPath(userPath);
        return Promise.resolve("Folder opened successfully");
      } else {
        return Promise.reject("Path exists, but it's not a folder");
      }
    } catch (err: any) {
      if (err.code === "ENOENT") {
        try {
          await fs.mkdir(userPath, { recursive: true });
          shell.openPath(userPath);
          return Promise.resolve("Folder created successfully");
        } catch (err2) {
          return Promise.reject(`Failed to create folder:${userPath}, ${err2}`);
        }
      }
    }
  });
  // Open a file
  ipcMain.handle("openFile", async (event: any, filePath: any) => {
    console.log(`open file ${filePath}`);
    shell.showItemInFolder(filePath);
    try {
      shell.showItemInFolder(filePath);
    } catch (err) {
      return Promise.reject(`openFile ${err}`);
    }
  });
  // Fetch remote text
  ipcMain.handle("getRemoteText", async (event: any, url, headers) => {
    console.log(`getRemoteText ${url}`);
    return utils.getRemoteText(url, headers);
  });
  // User Data Directory
  ipcMain.on("getUserDataPath", (event: any) => {
    event.returnValue = app.getPath("userData");
  });
  ipcMain.on("getTempPath", (event: any) => {
    event.returnValue = app.getPath("temp");
  });
  ipcMain.on("getDownloadsPath", (event: any) => {
    event.returnValue = app.getPath("downloads");
  });
  ipcMain.on("getLogsPath", (event: any) => {
    event.returnValue = app.getPath("logs");
  });
  ipcMain.on("getCrashPath", (event: any) => {
    event.returnValue = app.getPath("crashDumps");
  });
  // Query tasks
  ipcMain.on("getAutoImport", (event: any) => {
    event.returnValue = app.AutoImportTask.queryNextInvocations();
  });
  // Query hot update version
  // ipcMain.on("getBuildVersion", (event: any) => {
  //   event: any.returnValue = getBuildVersion();
  // });
  // Initialize tasks
  ipcMain.handle("initAutoImport", async (event: any, taskList: any) => {
    taskList.forEach((task: any) => app.AutoImportTask.addOrUpdateTask(task));
    app.AutoImportTask.cleanUp(taskList);
  });
  // Simulate crash
  ipcMain.handle("doCrash", async (event: any) => {
    process.crash();
  });
};
// 主进程和渲染进程通信
// 日志记录
type LoggerLevel = 'info' | 'warn' | 'error' | 'debug' | 'verbose' | 'silly';
export const ipcWindowInit = (mainWindow: any, ipcMain: any, app: any) => {
  // Function to safely register handle, removing any previous registrations
  function safeHandle(channel: any, listener: any) {
    // Register a new handler
    ipcMain.removeHandler(channel); //Deregister the old one to prevent duplicate registrations
    ipcMain.handle(channel, listener);
  }
  safeHandle("logger", (_event: any, level: LoggerLevel, content: string) => {
    console.log("🚀 ~ safeHandle ~ level:", level)
    console.log("🚀 ~ safeHandle ~ logger:", logger)
    logger[level](content);
  });
  // ipcMain.handle('logger', (_event: any, level: LoggerLevel, content: string) => {
  //   logger[level](content)
  // })

  // Open devTools
  safeHandle("openDevTools", async (event: any) => {
    mainWindow.webContents.openDevTools();
  });
  safeHandle("toggleDevTools", async (event: any) => {
    mainWindow.webContents.toggleDevTools();
  }); //toggle
  // Minimize
  safeHandle("miniWindow", async (event: any) => {
    mainWindow.minimize();
  });
  // Maximize
  safeHandle("maxWindow", async (event: any) => {
    mainWindow.maximize();
  });
  // Scale
  safeHandle("scaleWindow", async (event: any) => {
    if (mainWindow.isMaximized()) {
      mainWindow.unmaximize();
    } else {
      mainWindow.maximize();
    }
  });
  safeHandle("hideWindow", async (event: any) => {
    if (mainWindow.isVisible()) {
      mainWindow.hide();
    } else {
      console.log("window is hidden");
    }
  });
  // Close the window
  safeHandle("closeWindow", async (event: any) => {
    if (mainWindow && mainWindow.isClosable()) {
      mainWindow.close(); // Close the window
    }
  });

  safeHandle("activeWindow", async (event: any) => {
    if (mainWindow.isMinimized()) {
      mainWindow.restore();
    }
    mainWindow.show();
    mainWindow.focus();

    // For macOS, you can add this line
    if (process.platform === "darwin") {
      app.focus({ steal: true });
    }
  });
  // Force close the window
  safeHandle("forceCloseWindow", async (event: any, cfg: any) => {
    //win has a tray, handle it according to the user
    if (process.platform == "win32") {
      if (cfg?.isTray > 0) {
        if (mainWindow.isVisible()) {
          mainWindow.hide();
        }
      } else {
        // Destroy the window directly
        if (mainWindow && !mainWindow.isDestroyed()) {
          mainWindow.destroy();
        }
        console.log("quit by forceCloseWindow");
        app.quit(); // Force exit
      }
      return;
    }

    // Destroy the window directly in other cases
    if (mainWindow && !mainWindow.isDestroyed()) {
      mainWindow.destroy();
    }
    if (cfg?.isTray < 0) {
      console.log("quit by not tray");
      app.quit();
    }
  });
  // Cancel exit, requires window operation
  safeHandle("cancelQuit", async (event: any) => {
    if (app?.DelayQuitTimeId > 0) {
      clearTimeout(app.DelayQuitTimeId);
      app.DelayQuitTimeId = 0;
      console.log("receive cancel quit and cancel ok");
    } else {
      console.log("receive cancel quit");
    }
    if (mainWindow && !mainWindow.isDestroyed()) {
      if (mainWindow.isMinimized()) mainWindow.restore();
      mainWindow.focus();
      mainWindow.show();
    }
  });
  // Register random upgrade
  console.log("regiester new timeout");
  // checkUpdate(mainWindow, 20);0
  // // Register a new callback function
  // app.AutoImportTask.setCallBack((data: any, nextInvocation: any) => {
  //   if (mainWindow.isDestroyed()) {
  //     console.log("task mainWindow is distory");
  //   } else {
  //     console.log("autoImport", data, nextInvocation);
  //     mainWindow.webContents.send("autoImport", data, nextInvocation);
  //   }
  // });
};

// const checkUpdate = (mainWindow, timeout) => {
//   if (timeout && timeout > 0) {
//     //timeout ok
//   } else {
//     timeout = Math.floor(Math.random() * 3600 + 1800); // Within the range of 30 minutes to 1 hour and 30 minutes
//   }

//   if (timeoutId > 0) {
//     clearTimeout(timeoutId);
//     // Clear old timer
//   }

//   console.log("wait " + timeout + "s");
//   timeoutId = setTimeout(() => {
//     console.log("send checkUpdate, wait by" + timeout + "s");
//     if (mainWindow.isDestroyed()) {
//       console.log("mainWindow is distory");
//     } else {
//       mainWindow.webContents.send("checkUpdate", timeout);
//     }
//     checkUpdate(mainWindow); //recursive call
//   }, timeout * 1000);
// };

// module.exports = { ipcAppInit, ipcWindowInit };
